#ifndef DEVICEMANAGER_H
#define DEVICEMANAGER_H

#include "util.h"
#include "minimal_ogl.h"
#include "Device.h"
#include "IRpoint.h"

namespace LibWiimote{

class DevicesManager : private boost::noncopyable
{
public: 
	DevicesManager();
	static DevicesManager & GetCallbackInstance(); // Un genre de singleton. Workaround pour WiiYourself.

	// Callbacks pour WiiYourself
	void accel_changed_wiimote  (::wiimote & remote);
	void buttons_changed_wiimote(::wiimote & remote, ::wiimote_state changed);
	void accel_changed_nunchuk  (::wiimote & remote);
	void buttons_changed_nunchuk(::wiimote & remote, ::wiimote_state changed);
	void ir_changed_nunchuk     (::wiimote & remote);

	// Attente passive pour un OnKeyDown sur n'importe quelle wiimote.
	std::pair<::wiimote_state,::wiimote_state> WaitKeyPressed();

	int  ListWiimotes();
	void SortDevices (int neededDevices);
	int  CreateDevices();
	bool FindDevices(int neededDevices);
	
	void CalibrateDevices();
	void CalibrateIR();

	void EnableIR();
	void DisableIR();

	void LogDevices();
	void Draw();

	boost::shared_ptr<Device> getDevice(int i);
	int getNbDevices();

	boost::mutex ir_mutex;
	std::vector<IRPoint> getIRPoints(void);
	void RecalibratePoint(IRPoint & p);

private: 
	boost::shared_ptr<Device> findDevice(::wiimote & remote, EWhichPart part);

	boost::shared_ptr<Device> m_last_used_device;
	wiimote_state m_changed_buttons;

	std::vector<boost::shared_ptr<::wiimote> > m_wiimotes;
	std::vector<boost::shared_ptr<Device> >  m_devices;

	boost::mutex m_mutex;
	boost::condition_variable m_button_cond, m_accel_cond;

	bool m_selecting_controllers;
	bool m_calibrating;
	bool m_logging;

	std::vector<IRPoint> m_irpoints;
	float scale_x, scale_y, offset_x, offset_y;


	static DevicesManager * m_CallbackInstance; // Warkaround pour WiiYourself


};

}

#endif